/*
 * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <stdio.h>
#include <assert.h>
#include <errno.h>
#include <stdlib.h>
#include <utils/util.h>

#include <platsupport/clock.h>
#include <platsupport/plat/clock.h>

#include "../../services.h"

/* Register information sourced from "NVIDIA Tegra K1 Mobile Processor TECHNICAL REFERENCE MANUAL" */

#define CLK_REGISTER_ENTRY(a) {.reg_type = a}
#define CLK_REGISTER_ENTRY_SOURCE(b) {.reg_type = CLK_SOURCE, .st = {.clks = b}}
#define CLK_REGISTER_ENTRY_ENBRST(a,b) {.reg_type = CLK_ENBRST_DEVICES, .eb = {.rb = a, .at = b}}
#define NULL_CLK_REGISTER_ENTRY CLK_REGISTER_ENTRY(CLK_RESERVED)

/* Struct that describes register layout.
    this was done for quick lookup from device address to register type and info
    An array is used, sizeof(clk_register_t) is about 3 words (3 enums) because
    it is easier to declare everything inline using #defines, and the number of
    NULL_CLK_REGISTER_ENTRYs is about 30-35% of the array.
 */
const clk_register_t tk1_clk_registers[] = {
    // 0x0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_SOURCE_0
    CLK_REGISTER_ENTRY_ENBRST(REG_L, RST_VAL), // CLK_RST_CONTROLLER_RST_DEVICES_L_0
    CLK_REGISTER_ENTRY_ENBRST(REG_H, RST_VAL), // CLK_RST_CONTROLLER_RST_DEVICES_H_0
    CLK_REGISTER_ENTRY_ENBRST(REG_U, RST_VAL), // CLK_RST_CONTROLLER_RST_DEVICES_U_0
    // 0x10
    CLK_REGISTER_ENTRY_ENBRST(REG_L, ENB_VAL), // CLK_RST_CONTROLLER_CLK_OUT_ENB_L_0
    CLK_REGISTER_ENTRY_ENBRST(REG_H, ENB_VAL), // CLK_RST_CONTROLLER_CLK_OUT_ENB_H_0
    CLK_REGISTER_ENTRY_ENBRST(REG_U, ENB_VAL), // CLK_RST_CONTROLLER_CLK_OUT_ENB_U_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x20
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CCLK_BURST_POLICY_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SUPER_CCLK_DIVIDER_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SCLK_BURST_POLICY_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SUPER_SCLK_DIVIDER_0
    // 0x30
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x40
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_MASK_ARM_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_MISC_CLK_ENB_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0
    // 0x50
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_OSC_CTRL_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_PLL_LFSR_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_OSC_FREQ_DET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_OSC_FREQ_DET_STATUS_0
    // 0x60
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLE_SS_CNTL_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x70
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x80
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC_OUT_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC_MISC2_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC_MISC_0
    // 0x90
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLM_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLM_OUT_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLM_MISC1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLM_MISC2_0
    // 0xa0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_OUTA_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_OUTB_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_MISC_0
    // 0xb0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLA_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLA_OUT_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLA_MISC_0
    // 0xc0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLU_BASE_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLU_MISC_0
    // 0xd0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD_BASE_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD_MISC_0
    // 0xe0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_MISC_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLE_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLE_MISC_0
    // 0xf0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x100
    CLK_REGISTER_ENTRY_SOURCE(i2s1_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2S1_0
    CLK_REGISTER_ENTRY_SOURCE(i2s2_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2S2_0
    CLK_REGISTER_ENTRY_SOURCE(spdif_out_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_SPDIF_OUT_0
    CLK_REGISTER_ENTRY_SOURCE(spdif_in_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_SPDIF_IN_0
    // 0x110
    CLK_REGISTER_ENTRY_SOURCE(pwm_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_PWM_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(spi2_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SPI2_0
    CLK_REGISTER_ENTRY_SOURCE(spi3_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SPI3_0
    // 0x120
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(i2c1_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C1_0
    CLK_REGISTER_ENTRY_SOURCE(i2c5_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C5_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x130
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(spi1_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SPI1_0
    CLK_REGISTER_ENTRY_SOURCE(display_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_DISP1_0
    CLK_REGISTER_ENTRY_SOURCE(displayb_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_DISP2_0
    // 0x140
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(isp_r_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_ISP_0
    CLK_REGISTER_ENTRY_SOURCE(vi_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_VI_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x150
    CLK_REGISTER_ENTRY_SOURCE(sdmmc1_r_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC1_0
    CLK_REGISTER_ENTRY_SOURCE(sdmmc2_r_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC2_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x160
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(sdmmc4_r_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC4_0
    CLK_REGISTER_ENTRY_SOURCE(vfir_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_VFIR_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x170
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(hsi_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_HSI_0
    CLK_REGISTER_ENTRY_SOURCE(uarta_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_UARTA_0
    CLK_REGISTER_ENTRY_SOURCE(uartb_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_UARTB_0
    // 0x180
    CLK_REGISTER_ENTRY_SOURCE(host1x_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_HOST1X_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(hdmi_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_HDMI_0
    // 0x190
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(i2c2_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C2_0
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_EMC_0
    // 0x1a0
    CLK_REGISTER_ENTRY_SOURCE(uartc_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_UARTC_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(vi_sensor_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_VI_SENSOR_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x1b0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(spi4_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SPI4_0
    CLK_REGISTER_ENTRY_SOURCE(i2c3_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C3_0
    CLK_REGISTER_ENTRY_SOURCE(sdmmc3_r_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SDMMC3_0
    // 0x1c0
    CLK_REGISTER_ENTRY_SOURCE(uartd_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_UARTD_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(vde_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_VDE_0
    CLK_REGISTER_ENTRY_SOURCE(owr_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_OWR_0
    // 0x1d0
    CLK_REGISTER_ENTRY_SOURCE(nor_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_NOR_0
    CLK_REGISTER_ENTRY_SOURCE(csite_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_CSITE_0
    CLK_REGISTER_ENTRY_SOURCE(i2s0_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2S0_0
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_DTV_0
    // 0x1e0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x1f0
    CLK_REGISTER_ENTRY_SOURCE(msenc_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_MSENC_0
    CLK_REGISTER_ENTRY_SOURCE(tsec_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_TSEC_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_SPARE2_0
    // 0x200
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x210
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x220
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x230
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x240
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x250
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x260
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x270
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x280
    CLK_REGISTER_ENTRY_ENBRST(REG_X, ENB_VAL), // CLK_RST_CONTROLLER_CLK_OUT_ENB_X_0
    CLK_REGISTER_ENTRY_ENBRST(REG_X, ENB_SET), // CLK_RST_CONTROLLER_CLK_ENB_X_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_X, ENB_CLR), // CLK_RST_CONTROLLER_CLK_ENB_X_CLR_0
    CLK_REGISTER_ENTRY_ENBRST(REG_X, RST_VAL), // CLK_RST_CONTROLLER_RST_DEVICES_X_0
    // 0x290
    CLK_REGISTER_ENTRY_ENBRST(REG_X, RST_SET), // CLK_RST_CONTROLLER_RST_DEV_X_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_X, RST_CLR), // CLK_RST_CONTROLLER_RST_DEV_X_CLR_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x2a0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x2b0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x2c0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x2d0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x2e0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x2f0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_DFLL_BASE_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x300
    CLK_REGISTER_ENTRY_ENBRST(REG_L, RST_SET), // CLK_RST_CONTROLLER_RST_DEV_L_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_L, RST_CLR), // CLK_RST_CONTROLLER_RST_DEV_L_CLR_0
    CLK_REGISTER_ENTRY_ENBRST(REG_H, RST_SET), // CLK_RST_CONTROLLER_RST_DEV_H_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_H, RST_CLR), // CLK_RST_CONTROLLER_RST_DEV_H_CLR_0
    // 0x310
    CLK_REGISTER_ENTRY_ENBRST(REG_U, RST_SET), // CLK_RST_CONTROLLER_RST_DEV_U_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_U, RST_CLR), // CLK_RST_CONTROLLER_RST_DEV_U_CLR_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x320
    CLK_REGISTER_ENTRY_ENBRST(REG_L, ENB_SET), // CLK_RST_CONTROLLER_CLK_ENB_L_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_L, ENB_CLR), // CLK_RST_CONTROLLER_CLK_ENB_L_CLR_0
    CLK_REGISTER_ENTRY_ENBRST(REG_H, ENB_SET), // CLK_RST_CONTROLLER_CLK_ENB_H_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_H, ENB_CLR), // CLK_RST_CONTROLLER_CLK_ENB_H_CLR_0
    // 0x330
    CLK_REGISTER_ENTRY_ENBRST(REG_U, ENB_SET), // CLK_RST_CONTROLLER_CLK_ENB_U_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_U, ENB_CLR), // CLK_RST_CONTROLLER_CLK_ENB_U_CLR_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CCPLEX_PG_SM_OVRD_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x340
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPU_CMPLX_SET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR_0
    // 0x350
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_ENBRST(REG_V, RST_VAL), // CLK_RST_CONTROLLER_RST_DEVICES_V_0
    CLK_REGISTER_ENTRY_ENBRST(REG_W, RST_VAL), // CLK_RST_CONTROLLER_RST_DEVICES_W_0
    // 0x360
    CLK_REGISTER_ENTRY_ENBRST(REG_V, ENB_VAL), // CLK_RST_CONTROLLER_CLK_OUT_ENB_V_0
    CLK_REGISTER_ENTRY_ENBRST(REG_W, ENB_VAL), // CLK_RST_CONTROLLER_CLK_OUT_ENB_W_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CCLKG_BURST_POLICY_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SUPER_CCLKG_DIVIDER_0
    // 0x370
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CCLKLP_BURST_POLICY_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SUPER_CCLKLP_DIVIDER_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPUG_CMPLX_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPULP_CMPLX_0
    // 0x380
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL1_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_SOFTRST_CTRL2_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x390
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x3a0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x3b0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(mselect_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_MSELECT_0
    CLK_REGISTER_ENTRY_SOURCE(tsensor_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_TSENSOR_0
    CLK_REGISTER_ENTRY_SOURCE(i2s3_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2S3_0
    // 0x3c0
    CLK_REGISTER_ENTRY_SOURCE(i2s4_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2S4_0
    CLK_REGISTER_ENTRY_SOURCE(i2c4_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C4_0
    CLK_REGISTER_ENTRY_SOURCE(spi5_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SPI5_0
    CLK_REGISTER_ENTRY_SOURCE(spi6_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SPI6_0
    // 0x3d0
    CLK_REGISTER_ENTRY_SOURCE(audio_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_AUDIO_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(dam0_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_DAM0_0
    CLK_REGISTER_ENTRY_SOURCE(dam1_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_DAM1_0
    // 0x3e0
    CLK_REGISTER_ENTRY_SOURCE(dam2_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_DAM2_0
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_HDA2CODEC_2X_0
    CLK_REGISTER_ENTRY_SOURCE(actmon_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_ACTMON_0
    CLK_REGISTER_ENTRY_SOURCE(extperiph1_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH1_0
    // 0x3f0
    CLK_REGISTER_ENTRY_SOURCE(extperiph2_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH2_0
    CLK_REGISTER_ENTRY_SOURCE(extperiph3_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_EXTPERIPH3_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(i2c_slow_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C_SLOW_0
    // 0x400
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_SYS_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x410
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_SOR0_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x420
    CLK_REGISTER_ENTRY_SOURCE(sata_oob_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SATA_OOB_0
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_SATA_0
    CLK_REGISTER_ENTRY_SOURCE(hda_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_HDA_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x430
    CLK_REGISTER_ENTRY_ENBRST(REG_V, RST_SET), // CLK_RST_CONTROLLER_RST_DEV_V_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_V, RST_CLR), // CLK_RST_CONTROLLER_RST_DEV_V_CLR_0
    CLK_REGISTER_ENTRY_ENBRST(REG_W, RST_SET), // CLK_RST_CONTROLLER_RST_DEV_W_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_W, RST_CLR), // CLK_RST_CONTROLLER_RST_DEV_W_CLR_0
    // 0x440
    CLK_REGISTER_ENTRY_ENBRST(REG_V, ENB_SET), // CLK_RST_CONTROLLER_CLK_ENB_V_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_V, ENB_CLR), // CLK_RST_CONTROLLER_CLK_ENB_V_CLR_0
    CLK_REGISTER_ENTRY_ENBRST(REG_W, ENB_SET), // CLK_RST_CONTROLLER_CLK_ENB_W_SET_0
    CLK_REGISTER_ENTRY_ENBRST(REG_W, ENB_CLR), // CLK_RST_CONTROLLER_CLK_ENB_W_CLR_0
    // 0x450
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_CPUG_CMPLX_SET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_CPUG_CMPLX_CLR_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_CPULP_CMPLX_SET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_RST_CPULP_CMPLX_CLR_0
    // 0x460
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPUG_CMPLX_SET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPUG_CMPLX_CLR_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPULP_CMPLX_SET_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPULP_CMPLX_CLR_0
    // 0x470
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_CMPLX_STATUS_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_INTSTATUS_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_INTMASK_0
    // 0x480
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_UTMIP_PLL_CFG0_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_UTMIP_PLL_CFG1_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_UTMIP_PLL_CFG2_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLE_AUX_0
    // 0x490
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SATA_PLL_CFG0_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SATA_PLL_CFG1_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_PCIE_PLL_CFG_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_PROG_AUDIO_DLY_CLK_0
    // 0x4a0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S0_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S1_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S2_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S3_0
    // 0x4b0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_I2S4_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_AUDIO_SYNC_CLK_SPDIF_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD2_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD2_MISC_0
    // 0x4c0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_UTMIP_PLL_CFG3_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLREFE_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLREFE_MISC_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x4d0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_FINETRIM_BYP_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_FINETRIM_SELECT_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_FINETRIM_DR_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_FINETRIM_DF_0
    // 0x4e0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_FINETRIM_F_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CPU_FINETRIM_R_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC2_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC2_MISC_0_0
    // 0x4f0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC2_MISC_1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC2_MISC_2_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC2_MISC_3_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC3_BASE_0
    // 0x500
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC3_MISC_0_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC3_MISC_1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC3_MISC_2_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC3_MISC_3_0
    // 0x510
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_MISC_1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_MISC_2_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_MISC_3_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_XUSBIO_PLL_CFG0_0
    // 0x520
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_XUSBIO_PLL_CFG1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLE_AUX1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_RESHIFT_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_UTMIPLL_HW_PWRDN_CFG0_0
    // 0x530
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLU_HW_PWRDN_CFG0_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_XUSB_PLL_CFG0_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPU_MISC_0
    // 0x540
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPUG_MISC_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_CPULP_MISC_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_HW_CTRL_CFG_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_SW_RAMP_CFG_0
    // 0x550
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLX_HW_CTRL_STATUS_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_SPARE_REG0_0
    // 0x560
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x570
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD2_SS_CFG_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD2_SS_CTRL1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLD2_SS_CTRL2_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x580
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x590
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLDP_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLDP_MISC_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLDP_SS_CFG_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLDP_SS_CTRL1_0
    // 0x5a0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLDP_SS_CTRL2_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC4_BASE_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC4_MISC_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC4_SS_CFG_0
    // 0x5b0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC4_SS_CTRL1_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLC4_SS_CTRL2_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x5c0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_SPARE0_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_CLK_SPARE1_0
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_GPU_ISOB_CTRL_0
    // 0x5d0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x5e0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x5f0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x600
    CLK_REGISTER_ENTRY_SOURCE(xusb_core_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_HOST_0
    CLK_REGISTER_ENTRY_SOURCE(xusb_falcon_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FALCON_0
    CLK_REGISTER_ENTRY_SOURCE(xusb_fs_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_FS_0
    CLK_REGISTER_ENTRY_SOURCE(xusb_core_dev_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_CORE_DEV_0
    // 0x610
    CLK_REGISTER_ENTRY_SOURCE(NUM_OTHER_CLOCKS), // TODO CLK_RST_CONTROLLER_CLK_SOURCE_XUSB_SS_0
    CLK_REGISTER_ENTRY_SOURCE(cilab_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_CILAB_0
    CLK_REGISTER_ENTRY_SOURCE(cilcd_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_CILCD_0
    CLK_REGISTER_ENTRY_SOURCE(cile_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_CILE_0
    // 0x620
    CLK_REGISTER_ENTRY_SOURCE(dsia_lp_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_DSIA_LP_0
    CLK_REGISTER_ENTRY_SOURCE(dsib_lp_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_DSIB_LP_0
    CLK_REGISTER_ENTRY_SOURCE(entropy_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_ENTROPY_0
    CLK_REGISTER_ENTRY_SOURCE(dvfs_ref_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_REF_0
    // 0x630
    CLK_REGISTER_ENTRY_SOURCE(dvfs_soc_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_DVFS_SOC_0
    CLK_REGISTER_ENTRY_SOURCE(traceclkin_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_TRACECLKIN_0
    CLK_REGISTER_ENTRY_SOURCE(adx0_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_ADX0_0
    CLK_REGISTER_ENTRY_SOURCE(amx0_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_AMX0_0
    // 0x640
    CLK_REGISTER_ENTRY_SOURCE(emc_latency_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_EMC_LATENCY_0
    CLK_REGISTER_ENTRY_SOURCE(soc_therm_t), // CLK_RST_CONTROLLER_CLK_SOURCE_SOC_THERM_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    // 0x650
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(vi_sensor2_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_VI_SENSOR2_0
    CLK_REGISTER_ENTRY_SOURCE(i2c6_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_I2C6_0
    // 0x660
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY_SOURCE(emc_dll_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_EMC_DLL_0
    CLK_REGISTER_ENTRY_SOURCE(hdmi_audio_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_HDMI_AUDIO_0
    CLK_REGISTER_ENTRY_SOURCE(clk72mhz_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_CLK72MHZ_0
    // 0x670
    CLK_REGISTER_ENTRY_SOURCE(adx1_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_ADX1_0
    CLK_REGISTER_ENTRY_SOURCE(amx1_r_clk), // CLK_RST_CONTROLLER_CLK_SOURCE_AMX1_0
    CLK_REGISTER_ENTRY_SOURCE(vic_clk_t), // CLK_RST_CONTROLLER_CLK_SOURCE_VIC_0
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_OUTC_0
    // 0x680
    CLK_REGISTER_ENTRY(CLK_PLL), // CLK_RST_CONTROLLER_PLLP_MISC1_0
    NULL_CLK_REGISTER_ENTRY, // Reserved
    NULL_CLK_REGISTER_ENTRY, // Reserved
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_EMC_DIV_CLK_SHAPER_CTRL_0
    // 0x690
    CLK_REGISTER_ENTRY(CLK_MISC), // CLK_RST_CONTROLLER_EMC_PLLC_SHAPER_CTRL_0
};

static clk_t *
tk1_car_get_clock(clock_sys_t *cs, enum clk_id id)
{
    assert(cs != NULL);
    return NULL;
}

static int
tk1_car_gate_enable(clock_sys_t* clock_sys,
                    enum clock_gate gate, enum clock_gate_mode mode)
{
    /* The TK1 CAR controller only supports enabling and disabling the clock
     * signal to a device: there are no idle/sleep clock modes, so we ignore
     * CLKGATE_IDLE and CLKGATE_SLEEP.
     */
    if (clock_sys == NULL) {
        ZF_LOGE("Invalid driver instance handle!");
        return -EINVAL;
    }
    if (mode != CLKGATE_ON && mode != CLKGATE_OFF) {
        ZF_LOGE("Invalid clock gate mode %d!", mode);
        return -EINVAL;
    }

    return 0;
}

int
tegra_car_init(void *regs_vaddr, clock_sys_t *cs)
{
    if (regs_vaddr == NULL) {
        ZF_LOGE("MMIO vaddr for CAR regs cannot be NULL!");
        return -EINVAL;
    }

    cs->priv = regs_vaddr;

    cs->gate_enable = &tk1_car_gate_enable;
    cs->get_clock = &tk1_car_get_clock;
    return 0;
}

int
clock_sys_init(ps_io_ops_t* o, clock_sys_t* clock_sys)
{
    void *car_vaddr = NULL;

    if (o == NULL || clock_sys == NULL) {
        ZF_LOGE("Invalid io_ops or driver instance handle!");
        return -EINVAL;
    }

    MAP_IF_NULL(o, TK1_CLKCAR, car_vaddr);
    if (car_vaddr == NULL) {
        ZF_LOGE("Failed to map TK1 CAR registers into vmem.");
        return -1;
    }

    return tegra_car_init(car_vaddr, clock_sys);
}
